﻿using MongoDB.Driver;
using System.Linq.Expressions;

namespace YNTK.Data.MongoDB.Repositorie
{
    /// <summary>
    /// MongoDB仓储接口
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    public partial interface IMongoDBRepository<TEntity>
        where TEntity : class, new()
    {
        /// <summary>
        /// 检查表是否存在
        /// </summary>
        /// <param name="collectionName">数据集</param>
        /// <returns></returns>
        bool Exists(string collectionName);

        /// <summary>
        /// 检查表是否存在
        /// </summary>
        /// <param name="collectionName">数据集</param>
        /// <returns></returns>
        Task<bool> ExistsAsync(string collectionName);

        /// <summary>  
        /// 创建索引   
        /// </summary>  
        bool CreateIndex();

        /// <summary>
        /// 添加一条数据
        /// </summary>
        /// <param name="entity">添加的实体</param>
        /// <param name="name">数据集</param>
        /// <returns></returns>
        bool Add(TEntity entity, string name);

        /// <summary>
        /// 异步添加一条数据
        /// </summary>
        /// <param name="entity">添加的实体</param>
        /// <param name="name">数据集</param>
        /// <returns></returns>
        Task<bool> AddAsync(TEntity entity, string name);

        /// <summary>  
        /// 将数据插入进数据库  
        /// </summary>  
        /// <param name="entity">需要插入数据库的具体实体</param>  
        /// <param name="name">指定插入的集合</param>  
        bool Insert(TEntity entity, string name);

        /// <summary>
        /// 批量插入
        /// </summary>
        /// <param name="entities">实体集合</param>
        /// <param name="name">数据集</param>
        /// <returns></returns>
        bool AddList(List<TEntity> entities, string name);

        /// <summary>
        /// 异步批量插入
        /// </summary>
        /// <param name="entities">实体集合</param>
        /// <param name="name">数据集</param>
        /// <returns></returns>
        Task<bool> AddListAsync(List<TEntity> entities, string name);

        /// <summary>  
        /// 批量插入数据  
        /// </summary>  
        /// <param name="list">需要插入数据的列表</param>  
        /// <param name="name">指定要插入的集合</param>  
        bool InsertBatch(List<TEntity> list, string name);

        /// <summary>
        /// 修改一条数据
        /// </summary>
        /// <param name="entity">添加的实体</param>
        /// <param name="name">数据集</param>
        /// <param name="id"></param>
        /// <returns></returns>
        public UpdateResult Update(TEntity entity, string name, string id);

        /// <summary>
        /// 异步修改一条数据
        /// </summary>
        /// <param name="entity">添加的实体</param>
        /// <param name="name">数据集</param>
        /// <param name="id"></param>
        /// <returns></returns>
        Task<UpdateResult> UpdateAsync(TEntity entity, string name, string id);

        /// <summary>
        /// 异步修改一条数据
        /// </summary>
        /// <param name="entity">添加的实体</param>
        /// <param name="name">数据集</param>
        /// <param name="filter">条件</param>
        /// <returns></returns>
        Task<UpdateResult> UpdateAsync(TEntity entity, string name,Expression<Func<TEntity, bool>> filter);

        /// <summary>
        /// 替换单个文档
        /// </summary>
        /// <param name="entity">添加的实体</param>
        /// <param name="name">数据集</param>
        /// <param name="filter">条件</param>
        /// <returns></returns>
        Task<ReplaceOneResult> ReplaceOneAsync(TEntity entity, string name,Expression<Func<TEntity, bool>> filter);

        /// <summary>  
        /// 更新数据  
        /// </summary>  
        /// <param name="query">更新数据的查询</param>  
        /// <param name="update">需要更新的文档</param>  
        /// <param name="name">指定更新集合的名称</param>  
        /// <param name="id">ObjectId的键</param>
        bool Update(IMongoQuery query, IMongoUpdate update, string name, string id);

        /// <summary>
        /// 批量修改数据
        /// </summary>
        /// <param name="dic">要修改的字段</param>
        /// <param name="name">数据集</param>
        /// <param name="filter">修改条件</param>
        /// <returns></returns>
        UpdateResult UpdateManay(Dictionary<string, string> dic, string name, FilterDefinition<TEntity> filter);

        /// <summary>
        /// 批量修改数据
        /// </summary>
        /// <param name="entities">实体集合</param>
        /// <param name="name">数据集</param>
        /// <returns></returns>
        Task<int> UpdateManayAsync(List<TEntity> entities, string name);

        /// <summary>
        /// 异步批量修改数据
        /// </summary>
        /// <param name="dic">要修改的字段</param>
        /// <param name="name">数据集</param>
        /// <param name="filter">修改条件</param>
        /// <returns></returns>
        Task<UpdateResult> UpdateManayAsync(Dictionary<string, string> dic, string name, FilterDefinition<TEntity> filter);

        /// <summary>
        /// 删除一条数据
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="id">objectId</param>
        /// <returns></returns>
        DeleteResult Delete(string name, string id);

        /// <summary>  
        /// 移除指定的数据  
        /// </summary>  
        /// <param name="query">移除的数据条件</param>  
        /// <param name="name">指定的集合名词</param>  
        bool Remove(IMongoQuery query, string name);

        /// <summary>
        /// 异步删除一条数据
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="id">objectId</param>
        /// <returns></returns>
        Task<DeleteResult> DeleteAsync(string name, string id);

        /// <summary>
        /// 删除多条数据
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="filter">删除的条件</param>
        /// <returns></returns>
        DeleteResult DeleteMany(string name, FilterDefinition<TEntity> filter);

        /// <summary>
        /// 根据条件删除数据
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="where">删除的条件</param>
        /// <returns></returns>
        long Delete(string name, Expression<Func<TEntity, bool>> where);

        /// <summary>
        /// 异步删除多条数据
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="filter">删除的条件</param>
        /// <returns></returns>
        Task<DeleteResult> DeleteManyAsync(string name, FilterDefinition<TEntity> filter);

        /// <summary>
        /// 异步删除多条数据
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="where">删除的条件</param>
        /// <returns></returns>
        Task<long> DeleteAsync(string name, Expression<Func<TEntity, bool>> where);

        /// <summary>
        /// 根据id查询一条数据
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="id">objectid</param>
        /// <param name="field">要查询的字段，不写时查询全部</param>
        /// <returns></returns>
        TEntity Get(string name, string id, string[]? field = null);

        /// <summary>
        /// 根据条件获取一条数据
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="whereExpression">条件</param>
        /// <returns></returns>
        TEntity Get(string name, Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>
        /// 获取一条数据
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        Task<TEntity> GetAsync(string name, Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>
        /// 异步根据id查询一条数据
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="id">objectid</param>
        /// <param name="field">要查询的字段，不写时查询全部</param>
        /// <returns></returns>
        Task<TEntity> GetAsync(string name, string id, string[]? field = null);

        /// <summary>
        /// 查询集合
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="filter">查询条件</param>
        /// <param name="field">要查询的字段,不写时查询全部</param>
        /// <param name="sort">要排序的字段</param>
        /// <returns></returns>
        List<TEntity> GetList(string name, FilterDefinition<TEntity> filter, string[]? field = null, SortDefinition<TEntity>? sort = null);

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        Task<List<TEntity>> GetListAsync(string name, Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>
        /// 根据条件获取条数
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="whereExpression">条件</param>
        /// <returns></returns>
        Task<long> CountAsync(string name, Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>
        /// 异步查询集合
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="filter">查询条件</param>
        /// <param name="field">要查询的字段,不写时查询全部</param>
        /// <param name="sort">要排序的字段</param>
        /// <returns></returns>
        Task<List<TEntity>> GetListAsync(string name, FilterDefinition<TEntity> filter, string[]? field = null, SortDefinition<TEntity>? sort = null);

        /// <summary>
        /// 分页查询集合
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="filter">查询条件</param>
        /// <param name="pageIndex">页码，从1开始</param>
        /// <param name="pageSize">页数据量</param>
        /// <param name="count">总条数</param>
        /// <param name="field">要查询的字段,不写时查询全部</param>
        /// <param name="sort">要排序的字段</param>
        /// <returns></returns>
        List<TEntity> GetList(string name, FilterDefinition<TEntity> filter, int pageIndex, int pageSize, out long count, string[]? field = null, SortDefinition<TEntity>? sort = null);

        /// <summary>
        /// 异步分页查询集合
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="filter">查询条件</param>
        /// <param name="pageIndex">页码，从1开始</param>
        /// <param name="pageSize">页数据量</param>
        /// <param name="field">要查询的字段,不写时查询全部</param>
        /// <param name="sort">要排序的字段</param>
        /// <returns></returns>
        Task<List<TEntity>> GetListAsync(string name, FilterDefinition<TEntity> filter, int pageIndex, int pageSize, string[] field = null, SortDefinition<TEntity> sort = null);

        /// <summary>
        /// 异步分页查询集合
        /// </summary>
        /// <param name="name">数据集</param>
        /// <param name="where">查询条件</param>
        /// <param name="pageIndex">页码，从1开始</param>
        /// <param name="pageSize">页数据量</param>
        /// <param name="field">要查询的字段,不写时查询全部</param>
        /// <param name="sort">要排序的字段</param>
        /// <returns>Item1.结果集 Item2.总条数 Item3.总页数</returns>
        Task<(List<TEntity>, int, int)> GetListAsync(string name, Expression<Func<TEntity, bool>> where,
            int pageIndex, int pageSize, string[]? field = null, SortDefinition<TEntity>? sort=null);
    }
}
